package org.itzixi.controller;

import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.itzixi.base.BaseInfoProperties;
import org.itzixi.grace.result.GraceJSONResult;
import org.itzixi.grace.result.ResponseStatusEnum;
import org.itzixi.pojo.Users;
import org.itzixi.pojo.bo.RegistLoginBO;
import org.itzixi.pojo.vo.UsersVO;
import org.itzixi.service.UsersService;
import org.itzixi.tasks.SMSTask;
import org.itzixi.utils.IPUtil;
import org.itzixi.utils.MyInfo;
import org.itzixi.utils.SMSUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import java.util.UUID;

@RestController
@RequestMapping("passport")
@Slf4j
public class PassportController extends BaseInfoProperties {
    //127.0.0.1:88/passport/getSMSCode?mobile=18931490480
    //127.0.0.1:1000/passport/getSMSCode?mobile=18931490480

    @Resource
    private SMSTask smsTask;
    @Resource
    private UsersService usersService;

    @PostMapping("getSMSCode")
    public GraceJSONResult getSMSCode(String mobile,
                                      HttpServletRequest  request) throws Exception{
        if(StringUtils.isBlank(mobile)){
            return GraceJSONResult.error();
        }

        //获得用户手机号/ip
        String userIp= IPUtil.getRequestIp(request);
        //限制该用户手机号/ip在60秒内只能获取一次验证码
        redis.setnx60s(MOBILE_SMSCODE+":"+userIp,mobile);

//        String code=String.valueOf( (int)((Math.random()*9+1)*100000) );
        String code="123456";

        smsTask.sendSMSInTask(MyInfo.getMobile(),code);

        //把验证码存入redis，用于后续登录/注册校验
        redis.set(MOBILE_SMSCODE+":"+mobile,code,30*60);

        return GraceJSONResult.ok();
    }

    @PostMapping("regist")
    public GraceJSONResult regist(@RequestBody @Valid RegistLoginBO registLoginBO,
                                  HttpServletRequest request) throws Exception{
        String mobile=registLoginBO.getMobile();
        String code=registLoginBO.getSmsCode();
        String nickname=registLoginBO.getNickname();
        //1. 从redis中获得验证码进行校验判断是否匹配
        String redisCode = redis.get(MOBILE_SMSCODE + ":" + mobile);
        if(StringUtils.isBlank(redisCode) || !redisCode.equalsIgnoreCase(code)){
            return GraceJSONResult.errorCustom(ResponseStatusEnum.SMS_CODE_ERROR);
        }
        //2.根据mobile查询数据库，如果用户存在，提示不能重复注册
        Users user = usersService.queryMobileIsExist(mobile);
        if(user==null){
            //2.1如果用查询数据库用户为空，则表示用户没有注册过，需要进行用户信息数据入库
            user = usersService.createUsers(mobile, nickname);
        }else{
            return GraceJSONResult.errorCustom(ResponseStatusEnum.USER_ALREADY_EXIST_ERROR);
        }

        //3.用户注册成功后，删除redis中的验证码
        redis.del(MOBILE_SMSCODE+":"+mobile);
        //4.设置用户分布式会话，保存用户的token令牌，存储到redis中
        String uToken= TOKEN_USER_PREFIX+SYMBOL_DOT+ UUID.randomUUID();
        //只能在一台设备登录
//        redis.set(REDIS_USER_TOKEN+":"+user.getId(),uToken);//设置分布式会话
        //可以在多台设备登录
        redis.set(REDIS_USER_TOKEN+":"+uToken,user.getId());

        //5.返回用户数据给前端
        UsersVO userVO = new UsersVO();
        BeanUtils.copyProperties(user,userVO);
        userVO.setUserToken(uToken);

        return GraceJSONResult.ok(userVO);
    }

    @PostMapping("login")
    public GraceJSONResult login(@RequestBody @Valid RegistLoginBO registLoginBO,
                                  HttpServletRequest request) throws Exception{
        String mobile=registLoginBO.getMobile();
        String code=registLoginBO.getSmsCode();
        //1. 从redis中获得验证码进行校验判断是否匹配
        String redisCode = redis.get(MOBILE_SMSCODE + ":" + mobile);
        if(StringUtils.isBlank(redisCode) || !redisCode.equalsIgnoreCase(code)){
            return GraceJSONResult.errorCustom(ResponseStatusEnum.SMS_CODE_ERROR);
        }
        //2.根据mobile查询数据库，如果用户存在，提示不能重复注册
        Users user = usersService.queryMobileIsExist(mobile);
        if(user==null){
            //2.1如果用查询数据库用户为空，则表示用户没有注册过，则返回错误信息
            return GraceJSONResult.errorCustom(ResponseStatusEnum.USER_NOT_EXIST_ERROR);
        }

        //4.设置用户分布式会话，保存用户的token令牌，存储到redis中
        String uToken= TOKEN_USER_PREFIX+SYMBOL_DOT+ UUID.randomUUID();
        //只能在一台设备登录
//        redis.set(REDIS_USER_TOKEN+":"+user.getId(),uToken);//设置分布式会话
        //可以在多台设备登录
        redis.set(REDIS_USER_TOKEN+":"+uToken,user.getId());
        //5.返回用户数据给前端
        UsersVO userVO = new UsersVO();
        BeanUtils.copyProperties(user,userVO);
        userVO.setUserToken(uToken);

        return GraceJSONResult.ok(userVO);
    }

    /**
     * 注册登录合并接口
     * @param registLoginBO
     * @param request
     * @return
     * @throws Exception
     */
    @PostMapping("registOrLogin")
    public GraceJSONResult registOrLogin(@RequestBody @Valid RegistLoginBO registLoginBO,
                                  HttpServletRequest request) throws Exception{
        String mobile=registLoginBO.getMobile();
        String code=registLoginBO.getSmsCode();
        String nickname=registLoginBO.getNickname();
        //1. 从redis中获得验证码进行校验判断是否匹配
        String redisCode = redis.get(MOBILE_SMSCODE + ":" + mobile);
        if(StringUtils.isBlank(redisCode) || !redisCode.equalsIgnoreCase(code)){
            return GraceJSONResult.errorCustom(ResponseStatusEnum.SMS_CODE_ERROR);
        }
        //2.根据mobile查询数据库，如果用户存在，则直接登录
        Users user = usersService.queryMobileIsExist(mobile);
        if(user==null){
            //2.1如果用查询数据库用户为空，则表示用户没有注册过，需要进行用户信息数据入库
            user = usersService.createUsers(mobile, nickname);
        }

        //3.用户注册成功后，删除redis中的验证码
        redis.del(MOBILE_SMSCODE+":"+mobile);
        //4.设置用户分布式会话，保存用户的token令牌，存储到redis中
        String uToken= TOKEN_USER_PREFIX+SYMBOL_DOT+ UUID.randomUUID();
        //只能在一台设备登录
//        redis.set(REDIS_USER_TOKEN+":"+user.getId(),uToken);//设置分布式会话
        //可以在多台设备登录
        redis.set(REDIS_USER_TOKEN+":"+uToken,user.getId());
        //5.返回用户数据给前端
        UsersVO userVO = new UsersVO();
        BeanUtils.copyProperties(user,userVO);
        userVO.setUserToken(uToken);

        return GraceJSONResult.ok(userVO);
    }

    @PostMapping("logout")
    public GraceJSONResult logout(@RequestParam String userId,
                                  HttpServletRequest request) throws Exception{
        //1.清除用户的分布式会话信息
        redis.del(REDIS_USER_TOKEN+":"+userId);
        return GraceJSONResult.ok();
    }
}
